home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Frameworks / TransSkel 3.18 / Demos / C Demos / DialogSkel / DialogSkel.c next >
Encoding:
C/C++ Source or Header  |  1994-11-04  |  13.5 KB  |  619 lines  |  [TEXT/KAHL]

  1. /*
  2.  * DialogSkel - TransSkel modeless dialog demonstration.
  3.  *
  4.  * 21 Apr 88 Version 1.00 Paul DuBois
  5.  * 29 Jan 89 Version 1.01
  6.  * - Conversion for TransSkel 2.0.
  7.  * 07 Jan 91 Version 1.02
  8.  * - Conversion for TransSkel 3.00.
  9.  * 05 Jun 93 Version 1.03
  10.  * - Fixed to compile under THINK C 6.0.
  11.  * 09 Oct 93
  12.  * - Catches suspend/resume events, hides/shows dialogs when these occur.
  13.  * 19 Nov 93
  14.  * - Does better job on suspend/resume.  Rather than using HideWindow() and
  15.  * ShowWindow(), uses ShowHide() to preserve stacking order.
  16.  * - Added regular document window to provide contrast in handling during
  17.  * suspend/resume and to provide a way to bring the application forward by
  18.  * clicking in a window.  (With just dialogs, all the windows are hidden
  19.  * on a suspend.)
  20.  * - Added menu hook to disable Edit menu items when document window is
  21.  * frontmost, since editing doesn't apply to it.
  22.  * - Added Close item to File menu.
  23.  * 09 Dec 93
  24.  * - Updated for TransSkel 3.05.
  25.  * - Flush mouse down on activate when document window wasn't frontmost
  26.  * to preserve stacking order.
  27.  * 30 Dec 93
  28.  * - Fixed bug where closing modeless window by clicking close box caused
  29.  * Visible checkbox to be unchecked in partner, but closing by selecting
  30.  * Close from File menu didn't.
  31.  * 31 Dec 93
  32.  * - Junked all the dialog item manipulation routines and replaced by calls
  33.  * to the equivalent routines that now make up part of the auxiliary
  34.  * component of TransSkel (these routines are new in TS 3.06).
  35.  * 18 Dec 93
  36.  * - Ditto for new 3.07 routines.
  37.  * 11 Feb 94
  38.  * - Minor revisions.
  39.  * 21 Feb 94
  40.  * - Updated for TransSkel 3.11.
  41.  * 23 Apr 94
  42.  * - Updated for TransSkel 3.13.
  43.  * - Since the document window is growable, draw the grow region, which wasn't
  44.  * being done before.
  45.  * 27 Apr 94
  46.  * - Added filter function for modeless dialogs.
  47.  * - Track cursor in edit text item and change to I-beam when inside.
  48.  * - Map return/enter to hits in the Accept button.  Draw bold outline around
  49.  * button.
  50.  * - Controls in dialogs go inactive when window is deactivated.  Added
  51.  * 'dctb' resource for the dialog windows so inactive controls draw in better
  52.  * gray on color monitors.
  53.  * 04 Nov 94
  54.  * - Updated for TransSkel 3.18 (Support for Universal headers, PowerPC,
  55.  * Metrowerks).
  56.  */
  57.  
  58. # include    "TransSkel.h"
  59.  
  60.  
  61. # define    normalHilite    0
  62. # define    dimHilite        255
  63.  
  64.  
  65.  
  66. typedef enum            /* menu ID numbers */
  67. {
  68.     fileMenuID = skelAppleMenuID + 1,
  69.     editMenuID
  70. };
  71.  
  72.  
  73. typedef enum
  74. {
  75.     mDlogRes = 1000,
  76.     aboutAlrtRes,        /* About... alert resource number */
  77.     docWindRes = 1000
  78. };
  79.  
  80.  
  81. typedef enum            /* File menu item numbers */
  82. {
  83.     showDlog1 = 1,
  84.     showDlog2,
  85.     showDoc,
  86.     closeWind,
  87.     fGrayLine,
  88.     quit
  89. };
  90.  
  91.  
  92. typedef enum             /* Edit menu item numbers */
  93. {
  94.     undo = 1,
  95.     eGrayLine,
  96.     cut,
  97.     copy,
  98.     paste,
  99.     clear
  100. };
  101.  
  102.  
  103. typedef enum                /* dialog item numbers */
  104. {
  105.     button1 = 1,
  106.     edit1,
  107.     static1,
  108.     radio1,
  109.     radio2,
  110.     radio3,
  111.     check1,
  112.     check2,
  113.     user1
  114. };
  115.  
  116. static pascal void    DrawIcon (DialogPtr dlog, short item);
  117.  
  118.  
  119. static DialogPtr    mDlog1;
  120. static DialogPtr    mDlog2;
  121. static WindowPtr    docWind;
  122. static short        iconNum1 = 0;
  123. static short        iconNum2 = 0;
  124.  
  125. static MenuHandle    fileMenu;
  126. static MenuHandle    editMenu;
  127.  
  128.  
  129. /*
  130.  * Set up a variable to point to the icon drawing procedure.  For 68K code this
  131.  * is just a direct pointers to DrawIcon().  For PowerPC code it is a
  132.  * routine descriptor into which is stuffed the address of DrawIcon().
  133.  */
  134.  
  135. # if skelPPC        /* PowerPC code */
  136.  
  137. static RoutineDescriptor    drawDesc =
  138.         BUILD_ROUTINE_DESCRIPTOR(uppUserItemProcInfo, DrawIcon);
  139. static UserItemUPP    drawIconProc = (UserItemUPP) &drawDesc;
  140.  
  141. # else                /* 68K code */
  142.  
  143. static UserItemUPP    drawIconProc = DrawIcon;
  144.  
  145. # endif
  146.  
  147.  
  148. /* ------------------- */
  149. /* Miscellaneous stuff */
  150. /* ------------------- */
  151.  
  152.  
  153. static pascal void
  154. DrawIcon (DialogPtr dlog, short item)
  155. {
  156. Handle    h;
  157. Rect    r;
  158.  
  159.     SkelGetDlogRect (dlog, item, &r);
  160.     h = GetIcon (dlog == mDlog1 ? iconNum1 : iconNum2);
  161.     PlotIcon (&r, h);
  162. }
  163.  
  164.  
  165. static void
  166. SetDlogRadio (DialogPtr dlog, short item)
  167. {
  168. DialogPtr    partner;
  169. GrafPtr        tmpPort;
  170. Rect        r;
  171.  
  172.     partner = (DialogPtr) GetWRefCon (dlog);
  173.     SkelSetDlogRadioButtonSet (dlog, radio1, radio3, item);
  174.  
  175.     if (partner == mDlog1)
  176.         iconNum1 = item - radio1;
  177.     else
  178.         iconNum2 = item - radio1;
  179.  
  180.     SkelGetDlogRect (partner, user1, &r);
  181.     GetPort (&tmpPort);
  182.     SetPort (partner);
  183.     InvalRect (&r);    /* invalidate item rect to generate update event */
  184.     SetPort (tmpPort);
  185. }
  186.  
  187.  
  188. /* ---------------------------------------- */
  189. /* Dialog window setup and handler routines */
  190. /* ---------------------------------------- */
  191.  
  192.  
  193. static pascal Boolean
  194. DlogFilter (DialogPtr dlog, EventRecord *evt, short *item)
  195. {
  196. Boolean    result = false;
  197. short    hilite;
  198. char    c;
  199. Str255    str;
  200.  
  201.     /*
  202.      * Dim Accept button if edit string is empty.  This must be checked
  203.      * on every event, not just null events.  Otherwise, if the user
  204.      * clears the string and immediately clicks Accept, there would be
  205.      * no intervening null event and the button would be active for the
  206.      * click.
  207.      *
  208.      * Always dim button if this is a deactivate or the dialog isn't
  209.      * frontmost.
  210.      */
  211.  
  212.     SkelGetDlogStr (dlog, edit1, str);
  213.     hilite = (str[0] == 0 ? dimHilite : normalHilite);
  214.     if (evt->what == activateEvt && (evt->modifiers & activeFlag) == 0)
  215.         hilite = dimHilite;
  216.     if (dlog != FrontWindow ())
  217.         hilite = dimHilite;
  218.     if (SkelSetDlogCtlHilite (dlog, button1, hilite))    /* did button change state? */
  219.         SkelDrawButtonOutline (SkelGetDlogCtl (dlog, button1));
  220.  
  221.     switch (evt->what)
  222.     {
  223.     case nullEvent:
  224.         SkelSetDlogCursor (dlog);
  225.         break;
  226.     case keyDown:
  227.         if (SkelDlogMapKeyToButton (dlog, evt, item, button1, 0))
  228.             result = true;
  229.         break;
  230.     case updateEvt:
  231.         SkelDrawButtonOutline (SkelGetDlogCtl (dlog, button1));
  232.         break;
  233.     case activateEvt:
  234.         /* Accept button and outline are set above.  Set other controls here. */
  235.         hilite = (evt->modifiers & activeFlag ? normalHilite : dimHilite);
  236.         (void) SkelSetDlogCtlHilite (dlog, radio1, hilite);
  237.         (void) SkelSetDlogCtlHilite (dlog, radio2, hilite);
  238.         (void) SkelSetDlogCtlHilite (dlog, radio3, hilite);
  239.         (void) SkelSetDlogCtlHilite (dlog, check1, hilite);
  240.         (void) SkelSetDlogCtlHilite (dlog, check2, hilite);
  241.         break;
  242.     }
  243.     return (result);
  244. }
  245.  
  246.  
  247. static pascal void
  248. DlogSelect (DialogPtr actor, short item)
  249. {
  250. DialogPtr    partner;
  251. Str255        title;
  252. short        value;
  253.  
  254.     partner = (DialogPtr) GetWRefCon (actor);
  255.     switch (item)
  256.     {
  257.     case button1:
  258.         SkelGetDlogStr (actor, edit1, title);
  259.         SetWTitle (partner, title);
  260.         break;
  261.  
  262.     /* set radio buttons */
  263.  
  264.     case radio1:
  265.     case radio2:
  266.     case radio3:
  267.         SetDlogRadio (actor, item);
  268.         break;
  269.  
  270.     /* flip check boxes */
  271.  
  272.     case check1:
  273.         if (SkelToggleDlogCtlValue (actor, item))
  274.             ShowWindow (partner);
  275.         else
  276.             HideWindow (partner);
  277.         break;
  278.  
  279.     case check2:
  280.         value = SkelToggleDlogCtlValue (actor, item);
  281.         ((WindowPeek) partner)->goAwayFlag = (char) (value ? 255 : 0);
  282.         break;
  283.     }
  284. }
  285.  
  286.  
  287. static pascal void
  288. DlogClose (void)
  289. {
  290. DialogPtr    actor, partner;
  291.  
  292.     GetPort (&actor);
  293.     partner = (DialogPtr) GetWRefCon (actor);
  294.     HideWindow (actor);
  295.     SkelSetDlogCtlValue (partner, check1, 0);
  296. }
  297.  
  298.  
  299. static pascal void
  300. DlogClobber (void)
  301. {
  302. DialogPtr    dlog;
  303.  
  304.     GetPort (&dlog);
  305.     DisposeDialog (dlog);
  306. }
  307.  
  308.  
  309. static DialogPtr
  310. DemoDialog (StringPtr title, short h, short v)
  311. {
  312. DialogPtr    dlog;
  313.  
  314.     dlog = GetNewDialog (mDlogRes, nil, (WindowPtr) -1L);
  315.     MoveWindow (dlog, h, v, false);
  316.     SetWTitle (dlog, title);
  317.     (void) SkelDialog (dlog, DlogFilter, DlogSelect, DlogClose, DlogClobber);
  318.     return (dlog);
  319. }
  320.  
  321.  
  322. /* ------------------------------------------ */
  323. /* Document window setup and handler routines */
  324. /* ------------------------------------------ */
  325.  
  326.  
  327. static pascal void
  328. DocUpdate (Boolean resized)
  329. {
  330. }
  331.  
  332.  
  333. static pascal void
  334. DocActivate (Boolean active)
  335. {
  336. }
  337.  
  338.  
  339. static pascal void
  340. DocClobber (void)
  341. {
  342.     HideWindow (docWind);
  343.     DisposeWindow (docWind);
  344. }
  345.  
  346.  
  347. static void
  348. DocWindow (short h, short v)
  349. {
  350.     if (SkelQuery (skelQHasColorQD))
  351.         docWind = GetNewCWindow (docWindRes, nil, (WindowPtr) -1L);
  352.     else
  353.         docWind = GetNewWindow (docWindRes, nil, (WindowPtr) -1L);
  354.     (void) SkelWindow (docWind, nil, nil, DocUpdate, DocActivate, nil,
  355.                     DocClobber, nil, false);
  356.     MoveWindow (docWind, h, v, false);
  357. }
  358.  
  359.  
  360. /* ------------- */
  361. /* Menu handlers */
  362. /* ------------- */
  363.  
  364.  
  365. /*
  366.  * Handle selection of About... item from Apple menu
  367.  */
  368.  
  369. static pascal void
  370. DoAppleMenu (short item)
  371. {
  372.     (void) SkelAlert (aboutAlrtRes, SkelDlogFilter (nil, true),
  373.                                             skelPositionOnParentDevice);
  374.     SkelRmveDlogFilter ();
  375. }
  376.  
  377.  
  378. /*
  379.  * File menu handler
  380.  */
  381.  
  382. static pascal void
  383. DoFileMenu (short item)
  384. {
  385.     switch (item)
  386.     {
  387.     case showDlog1:
  388.         SelectWindow (mDlog1);
  389.         ShowWindow (mDlog1);
  390.         SkelSetDlogCtlValue (mDlog2, check1, 1);
  391.         break;
  392.     
  393.     case showDlog2:
  394.         SelectWindow (mDlog2);
  395.         ShowWindow (mDlog2);
  396.         SkelSetDlogCtlValue (mDlog1, check1, 1);
  397.         break;
  398.     
  399.     case showDoc:
  400.         SelectWindow (docWind);
  401.         ShowWindow (docWind);
  402.         break;
  403.  
  404.     case closeWind:
  405.         SkelClose (FrontWindow ());
  406.         break;
  407.  
  408.     case quit:
  409.         SkelStopEventLoop ();
  410.         break;
  411.     }
  412. }
  413.  
  414.  
  415. /*
  416.  * Handle Edit menu
  417.  */
  418.  
  419. static pascal void
  420. DoEditMenu (short item)
  421. {
  422. DialogPtr    dlog;
  423.  
  424.     if (SystemEdit (item - 1))        /* if DA handled operation, return */
  425.         return;
  426.  
  427.     /* if front window is document window, do nothing */
  428.     dlog = (DialogPtr) FrontWindow ();
  429.     if (((WindowPeek) dlog)->windowKind != dialogKind)
  430.         return;
  431.  
  432.     switch (item)
  433.     {
  434.     case cut:
  435.         DlgCut (dlog);
  436.         (void) ZeroScrap ();
  437.         (void) TEToScrap ();
  438.         break;
  439.  
  440.     case copy:
  441.         DlgCopy (dlog);
  442.         (void) ZeroScrap ();
  443.         (void) TEToScrap ();
  444.         break;
  445.  
  446.     case paste:
  447.         (void) TEFromScrap ();
  448.         DlgPaste (dlog);
  449.         break;
  450.  
  451.     case clear:
  452.         DlgDelete (dlog);
  453.         break;
  454.     }
  455. }
  456.  
  457.  
  458. /*
  459.  * Adjust menus when mouse click occurs in menu bar, before
  460.  * menus are shown.
  461.  */
  462.  
  463. static pascal void
  464. AdjustMenus (void)
  465. {
  466. WindowPtr    w = FrontWindow ();
  467.  
  468.     if (w == (WindowPtr) nil)
  469.         DisableItem (fileMenu, closeWind);
  470.     else
  471.         EnableItem (fileMenu, closeWind);
  472.  
  473.     if (w == docWind)
  474.     {
  475.         DisableItem (editMenu, undo);
  476.         DisableItem (editMenu, cut);
  477.         DisableItem (editMenu, copy);
  478.         DisableItem (editMenu, paste);
  479.         DisableItem (editMenu, clear);
  480.     }
  481.     else
  482.     {
  483.         /* modeless dialog or DA -- dim undo for dialogs */
  484.         if (((WindowPeek) w)->windowKind == dialogKind)
  485.             DisableItem (editMenu, undo);
  486.         else
  487.             EnableItem (editMenu, undo);
  488.         EnableItem (editMenu, cut);
  489.         EnableItem (editMenu, copy);
  490.         EnableItem (editMenu, paste);
  491.         EnableItem (editMenu, clear);
  492.     }
  493. }
  494.  
  495.  
  496. /* ---------------------- */
  497. /* Suspend/resume handler */
  498. /* ---------------------- */
  499.  
  500.  
  501. /*
  502.  * On a suspend, hide the dialog windows and deactivate the frontmost window
  503.  * if there is one.  Normally the system will unhilite the front window, but
  504.  * since hiding the dialogs may cause the document window to be hilited, it's
  505.  * necessary to unhilite whatever window's frontmost after hiding the windows.
  506.  *
  507.  * Similarly, on an activate, the system may hilite the frontmost window, but
  508.  * but showing the dialogs may result in a new frontmost window, which then
  509.  * needs to be hilited.  If the document window was not frontmost when the
  510.  * suspend occurred, the system will also generate a mouse click to bring it
  511.  * forward.  To preserve the stacking order, suck the mouse click out of the
  512.  * event queue.
  513.  */
  514.  
  515. static pascal void
  516. SuspendResume (Boolean inForeground)
  517. {
  518. WindowPtr    w;
  519. EventRecord    event;
  520. static Boolean    hidden1;
  521. static Boolean    hidden2;
  522.  
  523.     if (!inForeground)
  524.     {
  525.         hidden1 = hidden2 = false;
  526.         if (((WindowPeek) mDlog1)->visible)
  527.         {
  528.             ShowHide (mDlog1, false);
  529.             hidden1 = true;
  530.         }
  531.         if (((WindowPeek) mDlog2)->visible)
  532.         {
  533.             ShowHide (mDlog2, false);
  534.             hidden2 = true;
  535.         }
  536.         if ((w = FrontWindow ()) != (WindowPtr) nil)
  537.         {
  538.             HiliteWindow (w, false);
  539.             SkelActivate (w, false);
  540.         }
  541.     }
  542.     else
  543.     {
  544.         if ((w = FrontWindow ()) != (WindowPtr) nil)
  545.             HiliteWindow (w, false);
  546.         if (hidden1)
  547.             ShowHide (mDlog1, true);
  548.         if (hidden2)
  549.             ShowHide (mDlog2, true);
  550.         if ((w = FrontWindow ()) != (WindowPtr) nil)
  551.         {
  552.             HiliteWindow (w, true);
  553.             SkelActivate (w, true);
  554.         }
  555.         if (EventAvail (mDownMask, &event))
  556.             (void) GetNextEvent (mDownMask, &event);
  557.     }
  558. }
  559.  
  560.  
  561. /* ------------ */
  562. /* Main program */
  563. /* ------------ */
  564.  
  565.  
  566. int
  567. main (void)
  568. {
  569.     SkelInit ((SkelInitParamsPtr) nil);
  570.  
  571.     SkelSetSuspendResume (SuspendResume);
  572.  
  573.     /* 311 = ellipsis */
  574.     SkelApple ((StringPtr) "\pAbout DialogSkel\311", DoAppleMenu);
  575.  
  576.     fileMenu = NewMenu (fileMenuID, (StringPtr) "\pFile");
  577.     AppendMenu (fileMenu, (StringPtr) "\pShow Dialog 1;Show Dialog 2;Show Doc Window");
  578.     AppendMenu (fileMenu, (StringPtr) "\pClose/W;(-;Quit/Q");
  579.     (void) SkelMenu (fileMenu, DoFileMenu, nil, false, false);
  580.  
  581.     editMenu = NewMenu (editMenuID, (StringPtr) "\pEdit");
  582.     AppendMenu (editMenu, (StringPtr) "\p(Undo/Z;(-;Cut/X;Copy/C;Paste/V;Clear");
  583.     (void) SkelMenu (editMenu, DoEditMenu, nil, false, false);
  584.     
  585.     DrawMenuBar ();
  586.     SkelSetMenuHook (AdjustMenus);
  587.     
  588.     DocWindow (100, 125);
  589.     
  590.     mDlog1 = DemoDialog ((StringPtr) "\pModeless Dialog 1", 50, 50);
  591.     mDlog2 = DemoDialog ((StringPtr) "\pModeless Dialog 2", 150, 200);
  592.     SetWRefCon (mDlog1, (long) mDlog2);
  593.     SetWRefCon (mDlog2, (long) mDlog1);
  594.     SkelSetDlogStr (mDlog1, edit1, (StringPtr) "\pModeless Dialog 2");
  595.     SkelSetDlogStr (mDlog2, edit1, (StringPtr) "\pModeless Dialog 1");
  596.     SkelSetDlogProc (mDlog1, user1, drawIconProc);
  597.     SkelSetDlogProc (mDlog2, user1, drawIconProc);
  598.     SkelSetDlogRadioButtonSet (mDlog1, radio1, radio3, radio1);
  599.     SkelSetDlogRadioButtonSet (mDlog2, radio1, radio3, radio1);
  600.     SkelSetDlogCtlValue (mDlog1, check1, 1);
  601.     SkelSetDlogCtlValue (mDlog2, check1, 1);
  602.     SkelSetDlogCtlValue (mDlog1, check2, 1);
  603.     SkelSetDlogCtlValue (mDlog2, check2, 1);
  604.  
  605.     SelectWindow (docWind);
  606.     ShowWindow (docWind);
  607.     SkelDoEvents (activMask + updateMask);
  608.     SelectWindow (mDlog1);
  609.     ShowWindow (mDlog1);
  610.     SkelDoEvents (activMask + updateMask);
  611.     SelectWindow (mDlog2);
  612.     ShowWindow (mDlog2);
  613.     SkelDoEvents (activMask + updateMask);
  614.  
  615.     SkelEventLoop ();
  616.     SkelCleanup ();
  617. }
  618.  
  619.